from models.database import SessionLocal, create_db
from models.do.user_do import UserModel
from models.do.role_do import RoleModel
from models.do.permission_do import PermissionModel
from models.do.user_role_do import UserRoleModel
from models.do.role_permission_do import RolePermissionModel
from utils.id_util import generate_id
from utils.password_util import hash_or_store_password, encrypt_username
from sqlalchemy.exc import IntegrityError # Import IntegrityError

DEFAULT_ADMIN_PASSWORD = "admin"

def create_initial_data():
    create_db() # Ensure tables are created

    with SessionLocal() as db:
        try:
            # Create Roles
            admin_role = RoleModel(id=generate_id(), name="admin", description="Administrator role with full access")
            user_role = RoleModel(id=generate_id(), name="user", description="Standard user role with basic access")
            db.add_all([admin_role, user_role])
            db.commit()
            db.refresh(admin_role)
            db.refresh(user_role)

            # Create Permissions
            # Auth Permissions
            auth_login_permission = PermissionModel(id=generate_id(), name="auth:login", description="User login", endpoint="/auth/login", method="POST")
            auth_register_permission = PermissionModel(id=generate_id(), name="auth:register", description="User registration", endpoint="/auth/register", method="POST")
            auth_assign_role_permission = PermissionModel(id=generate_id(), name="auth:assign_role", description="Assign role to user", endpoint="/auth/assign-role", method="POST")
            auth_remove_role_permission = PermissionModel(id=generate_id(), name="auth:remove_role", description="Remove role from user", endpoint="/auth/remove-role", method="DELETE")
            auth_delete_user_permission = PermissionModel(id=generate_id(), name="auth:delete_user", description="Delete user from auth controller", endpoint="/auth/delete-user", method="DELETE")

            # Crime Permissions
            crime_read_permission = PermissionModel(id=generate_id(), name="crime:read", description="Read crime data", endpoint="/crimes", method="GET")
            crime_create_permission = PermissionModel(id=generate_id(), name="crime:create", description="Create crime data", endpoint="/crimes", method="POST")
            crime_update_permission = PermissionModel(id=generate_id(), name="crime:update", description="Update crime data", endpoint="/crimes/{crime_id}", method="PUT")
            crime_delete_permission = PermissionModel(id=generate_id(), name="crime:delete", description="Delete crime data", endpoint="/crimes/{crime_id}", method="DELETE")
            
            # User Permissions
            user_read_all_permission = PermissionModel(id=generate_id(), name="user:read_all", description="Read all users", endpoint="/users", method="GET")
            user_read_one_permission = PermissionModel(id=generate_id(), name="user:read_one", description="Read a single user", endpoint="/users/{user_id}", method="GET")
            user_update_permission = PermissionModel(id=generate_id(), name="user:update", description="Update users", endpoint="/users/{user_id}", method="PUT")
            user_delete_permission = PermissionModel(id=generate_id(), name="user:delete", description="Delete users", endpoint="/users/{user_id}", method="DELETE")
            user_search_permission = PermissionModel(id=generate_id(), name="user:search", description="Search users", endpoint="/users/search", method="GET")

            # Role Permissions
            role_create_permission = PermissionModel(id=generate_id(), name="role:create", description="Create roles", endpoint="/roles", method="POST")
            role_read_all_permission = PermissionModel(id=generate_id(), name="role:read_all", description="Read all roles", endpoint="/roles", method="GET")
            role_read_one_permission = PermissionModel(id=generate_id(), name="role:read_one", description="Read a single role", endpoint="/roles/{role_id}", method="GET")
            role_update_permission = PermissionModel(id=generate_id(), name="role:update", description="Update roles", endpoint="/roles/{role_id}", method="PUT")
            role_delete_permission = PermissionModel(id=generate_id(), name="role:delete", description="Delete roles", endpoint="/roles/{role_id}", method="DELETE")

            db.add_all([
                auth_login_permission, auth_register_permission, auth_assign_role_permission, auth_remove_role_permission, auth_delete_user_permission,
                crime_read_permission, crime_create_permission, crime_update_permission, crime_delete_permission,
                user_read_all_permission, user_read_one_permission, user_update_permission, user_delete_permission, user_search_permission,
                role_create_permission, role_read_all_permission, role_read_one_permission, role_update_permission, role_delete_permission
            ])
            db.commit()
            db.refresh(auth_login_permission)
            db.refresh(auth_register_permission)
            db.refresh(auth_assign_role_permission)
            db.refresh(auth_remove_role_permission)
            db.refresh(auth_delete_user_permission)
            db.refresh(crime_read_permission)
            db.refresh(crime_create_permission)
            db.refresh(crime_update_permission)
            db.refresh(crime_delete_permission)
            db.refresh(user_read_all_permission)
            db.refresh(user_read_one_permission)
            db.refresh(user_update_permission)
            db.refresh(user_delete_permission)
            db.refresh(user_search_permission)
            db.refresh(role_create_permission)
            db.refresh(role_read_all_permission)
            db.refresh(role_read_one_permission)
            db.refresh(role_update_permission)
            db.refresh(role_delete_permission)

            # Assign Permissions to Roles
            # Admin gets all permissions
            db.add_all([
                RolePermissionModel(role_id=admin_role.id, permission_id=auth_login_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=auth_register_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=auth_assign_role_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=auth_remove_role_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=auth_delete_user_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=crime_read_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=crime_create_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=crime_update_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=crime_delete_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=user_read_all_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=user_read_one_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=user_update_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=user_delete_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=user_search_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=role_create_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=role_read_all_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=role_read_one_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=role_update_permission.id),
                RolePermissionModel(role_id=admin_role.id, permission_id=role_delete_permission.id),
            ])
            # User gets read permission for crimes and register permission
            db.add_all([
                RolePermissionModel(role_id=user_role.id, permission_id=auth_login_permission.id),
                RolePermissionModel(role_id=user_role.id, permission_id=auth_register_permission.id),
                RolePermissionModel(role_id=user_role.id, permission_id=crime_read_permission.id),
            ])
            db.commit()

            # Create Default Admin User
            admin_user = UserModel(
                id=generate_id(),
                username=encrypt_username("admin"),
                hashed_password=hash_or_store_password(DEFAULT_ADMIN_PASSWORD),
                is_active=True,
                is_superuser=True
            )
            db.add(admin_user)
            db.commit()
            db.refresh(admin_user)

            # Assign Admin Role to Admin User
            db.add(UserRoleModel(user_id=admin_user.id, role_id=admin_role.id))
            db.commit()

            print("Initial data created: Admin user, roles, and permissions.")
        except IntegrityError:
            db.rollback()
            print("Initial data already exists. Skipping creation.")
        except Exception as e:
            db.rollback()
            print(f"An error occurred during initial data creation: {e}")


if __name__ == "__main__":
    create_initial_data()